package com.expert.miniapp.service.impl;

import com.expert.miniapp.dao.Instrument;
import com.expert.miniapp.dao.InstrumentMapper;
import com.expert.miniapp.dao.Laboratory;
import com.expert.miniapp.dao.LaboratoryMapper;
import com.expert.miniapp.dao.OtherResource;
import com.expert.miniapp.dao.OtherResourceMapper;
import com.expert.miniapp.dao.Recommendation;
import com.expert.miniapp.dao.RecommendationItem;
import com.expert.miniapp.dao.RecommendationItemMapper;
import com.expert.miniapp.dao.RecommendationMapper;
import com.expert.miniapp.dao.ResearchExpert;
import com.expert.miniapp.dao.ResearchExpertMapper;
import com.expert.miniapp.dao.TechAchievement;
import com.expert.miniapp.dao.TechAchievementMapper;
import com.expert.miniapp.dto.RecommendationItemDetailDTO;
import com.expert.miniapp.dto.RecommendationResponseDTO;
import com.expert.miniapp.service.RecommendationService;
import com.github.pagehelper.PageHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Recommendation service implementation.
 * Provides homepage recommendations and recommendation detail lookups.
 */
@Service
public class RecommendationServiceImpl implements RecommendationService {

    private static final Logger logger = LoggerFactory.getLogger(RecommendationServiceImpl.class);

    @Autowired
    private ResearchExpertMapper researchExpertMapper;

    @Autowired
    private TechAchievementMapper techAchievementMapper;

    @Autowired
    private InstrumentMapper instrumentMapper;

    @Autowired
    private LaboratoryMapper laboratoryMapper;

    @Autowired
    private OtherResourceMapper otherResourceMapper;

    @Autowired
    private RecommendationMapper recommendationMapper;

    @Autowired
    private RecommendationItemMapper recommendationItemMapper;

    @Override
    public Map<String, Object> getHomepageRecommendations(
            int expertCount,
            int achievementCount,
            int instrumentCount,
            int laboratoryCount,
            int otherResourceCount
    ) {
        logger.info(
                "Fetching homepage recommendations: expert={}, achievement={}, instrument={}, laboratory={}, other={}",
                expertCount, achievementCount, instrumentCount, laboratoryCount, otherResourceCount
        );

        Map<String, Object> result = new HashMap<>();

        try {
            if (expertCount > 0) {
                PageHelper.startPage(1, expertCount);
                List<ResearchExpert> experts = researchExpertMapper.findByWeightOrder();
                result.put("experts", experts);
            }

            if (achievementCount > 0) {
                PageHelper.startPage(1, achievementCount);
                List<TechAchievement> achievements = techAchievementMapper.findByWeightOrder();
                result.put("achievements", achievements);
            }

            if (instrumentCount > 0) {
                PageHelper.startPage(1, instrumentCount);
                List<Instrument> instruments = instrumentMapper.findByWeightOrder();
                result.put("instruments", instruments);
            }

            if (laboratoryCount > 0) {
                PageHelper.startPage(1, laboratoryCount);
                List<Laboratory> laboratories = laboratoryMapper.findByWeightOrder();
                result.put("laboratories", laboratories);
            }

            if (otherResourceCount > 0) {
                PageHelper.startPage(1, otherResourceCount);
                List<OtherResource> otherResources = otherResourceMapper.findByWeightOrder();
                result.put("otherResources", otherResources);
            }

            logger.info("Homepage recommendations prepared successfully with {} resource buckets", result.size());
            return result;

        } catch (Exception ex) {
            logger.error("Failed to load homepage recommendations", ex);
            throw new RuntimeException("Failed to load homepage recommendations: " + ex.getMessage(), ex);
        }
    }

    @Override
    public RecommendationResponseDTO getRecommendationDetail(String recommendationId) {
        logger.info("Fetching recommendation detail: {}", recommendationId);
        Recommendation recommendation = recommendationMapper.findById(recommendationId);
        if (recommendation == null) {
            throw new IllegalArgumentException("Recommendation not found: " + recommendationId);
        }
        List<RecommendationItem> items = recommendationItemMapper.findByRecommendationId(recommendationId);
        return buildResponseDTO(recommendation, items);
    }

    @Override
    public List<Recommendation> getRecommendationsByDemandId(String demandId) {
        logger.info("Fetching recommendations for demand {}", demandId);
        return recommendationMapper.findByDemandId(demandId);
    }

    @Override
    public RecommendationItem getRecommendationItemById(String itemId) {
        logger.info("Fetching recommendation item {}", itemId);
        RecommendationItem item = recommendationItemMapper.findByItemId(itemId);
        if (item == null) {
            throw new IllegalArgumentException("Recommendation item not found: " + itemId);
        }
        return item;
    }

    @Override
    public RecommendationItemDetailDTO getRecommendationItemDetail(String itemId) {
        logger.info("Fetching recommendation item detail: {}", itemId);
        RecommendationItemDetailDTO detail = recommendationItemMapper.findDetailByItemId(itemId);
        if (detail == null) {
            throw new IllegalArgumentException("Recommendation item not found: " + itemId);
        }
        return detail;
    }

    private RecommendationResponseDTO buildResponseDTO(Recommendation recommendation, List<RecommendationItem> items) {
        RecommendationResponseDTO dto = new RecommendationResponseDTO();
        dto.setRecommendationId(recommendation.getRecommendationId());
        dto.setDemandId(recommendation.getDemandId());
        dto.setCreatedAt(recommendation.getCreatedAt());
        dto.setItems(items);
        dto.setTotalCount(items != null ? items.size() : 0);

        RecommendationResponseDTO.ResourceStatistics statistics = new RecommendationResponseDTO.ResourceStatistics();
        statistics.setMatchedExpertCount(recommendation.getMatchedExpertCount());
        statistics.setMatchedAchievementCount(recommendation.getMatchedAchievementCount());
        statistics.setMatchedInstrumentCount(recommendation.getMatchedInstrumentCount());
        statistics.setMatchedLaboratoryCount(recommendation.getMatchedLaboratoryCount());
        statistics.setMatchedOtherCount(recommendation.getMatchedOtherCount());
        dto.setStatistics(statistics);

        return dto;
    }
}
